package org.codetranslators.common;

import java.util.HashMap;
import java.util.HashSet;
import java.util.Vector;

public class Utilities {
	/*
	 * Given the control flow graph and it's corresponding dominator tree, this function returns
	 * the dominance frontier for the
	 */
	public static HashMap<Node, HashSet<Node>> getDominanceFrontiers(ControlFlowGraph cfg, DominatorTree dominatorTree){
		HashMap<Node, HashSet<Node>> dominanceFrontiers = new HashMap();
		int numGraphNodes = cfg.getNumNodes();
		for(int i = 0; i < numGraphNodes; i++){
			Node node = cfg.getNode(i);
			Vector<Node> predecessors = node.getPredecessors();
			int numPreds = predecessors.size();
			if(numPreds > 1){
				// This node has more than predecessor
				Node immediateDominator = dominatorTree.getParentInTree(node);
				for(int j = 0; j < numPreds; j++){
					Node predecessor = predecessors.elementAt(j);
					Node runner = predecessor;
					while(runner != immediateDominator){

						HashSet<Node> members = (HashSet<Node>)dominanceFrontiers.get(runner);
						if(members == null) members = new HashSet<Node>();
						members.add(node);
						dominanceFrontiers.put(runner, members);

						runner = dominatorTree.getParentInTree(runner);
					}
				}
			}
		}
		return dominanceFrontiers;
	}

	public static void addToDominanceFrontier(HashMap<Node, HashSet<Node>> dominanceFrontiers, Node node, Node frontierMember){
		HashSet<Node> members = dominanceFrontiers.get(node);
		if(members == null) members = new HashSet<Node>();
		members.add(frontierMember);
		dominanceFrontiers.put(node, members);
	}
}
